/**
 * Copyright 2012 Roger Cockshutt
 * krakenbrau@gmail.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.googlecode.parallelrl;

import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.googlecode.parallelrl.data.DataFile;
import com.googlecode.parallelrl.data.ecs.ECSManager;
import com.googlecode.parallelrl.util.Point2D;

import java.lang.reflect.*;

/**
 * This class is responsible for loading the config and data files, and making its values accessible.
 * 
 * @author Roger Cockshutt
 *
 */
public abstract class Config {
	
	private static HashMap<String, String> configEntries;
	
	/**
	 * Relative path to the mob data file.
	 */
	public static String 								mobsFilePath = null;
	/**
	 * Relative path to the item data file.
	 */
	public static String								itemsFilePath = null;
	
	public static String								terrainFilePath = null;
	
	public static String								keysFilePath = null;
	
	public static HashMap<Integer, String>				keyMap = new HashMap<>();
	
	// Config file entries
	public static Point2D	windowSize;
	public static String	windowTitle;
	public static Point2D	mapWindowSize;
	public static Point2D	mapWindowPosition;
	public static Point2D	logWindowSize;
	public static Point2D	logWindowPosition;
	public static Point2D	statusWindowSize;
	public static Point2D	statusWindowPosition;
	public static Point2D	defaultLevelSize;
	public static Integer	fpsLimit;
	public static Integer	fpsPause;
	
	
	/**
	 * Loads Entity entries from all data files into their respective HashMaps.  Skips any data files
	 * with no file path given.
	 */
	public static void loadDataFiles() {
		if (keysFilePath != null) {
			if (ParallelRL.doDebug)
				System.out.println("Loading keys from " + keysFilePath);
			DataFile keysFile = new DataFile(keysFilePath);
			keysFile.read();
			keyMap = keysFile.loadKeys();
			if (ParallelRL.doDebug)
				System.out.println(keyMap.toString());
		}
		if (mobsFilePath != null) {
			if (ParallelRL.doDebug)
				System.out.println("Loading mobs from " + mobsFilePath);
			DataFile mobsFile = new DataFile(mobsFilePath);
			mobsFile.read();
			ECSManager.loadAssemblageData(mobsFile.getLines());
		}
		if (itemsFilePath != null) {
			if (ParallelRL.doDebug)
				System.out.println("Loading items from " + itemsFilePath);
			DataFile itemsFile = new DataFile(itemsFilePath);
			itemsFile.read();
			ECSManager.loadAssemblageData(itemsFile.getLines());
		}
		if (terrainFilePath != null) {
			if (ParallelRL.doDebug)
				System.out.println("Loading terrain from " + terrainFilePath);
			DataFile terrainFile = new DataFile(terrainFilePath);
			terrainFile.read();
			ECSManager.loadAssemblageData(terrainFile.getLines());
		}
	}
	
	/**
	 * Loads data from the config file.
	 * 
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 */
	public static void load() throws IllegalArgumentException, IllegalAccessException {
		if (ParallelRL.doDebug)
			System.out.println("Loading config...");
		DataFile configFile = new DataFile("config");
		configFile.read();
		configEntries = configFile.loadConfig();
		Field[] fields = Config.class.getFields();
		Matcher match;
		for (Field field : fields) {
			if (configEntries.containsKey(field.getName())) {
				if (ParallelRL.doDebug)
					System.out.println("Loading field " + field);
				Class<?> type = field.getType();
				if (type == Point2D.class) {
					match = Pattern.compile("([0-9]+), ?([0-9]+)").matcher(configEntries.get(field.getName()));
					if (match.find()) {
						int y = Integer.decode(match.group(1));
						int x = Integer.decode(match.group(2));
						field.set(null, new Point2D(y, x));
					}
				} else if (type == String.class) {
					field.set(null, configEntries.get(field.getName()));
				} else if (type == Integer.class) {
					field.set(null, Integer.valueOf(configEntries.get(field.getName())));
				}
			}
		}
		loadDataFiles();
	}

}
